//-------------------------------------------------------------------------
// Copyright (c) 2000-2010 Ufinity. All Rights Reserved.
//
// This software is the confidential and proprietary information of
// Ufinity
//
// Original author: Administrator
//
//-------------------------------------------------------------------------
// UFINITY MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
// THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE, OR NON-INFRINGEMENT. UFINITY SHALL NOT BE
// LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
// MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
//
// THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
// CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
// PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
// NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
// SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
// SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
// PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). UFINITY
// SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
// HIGH RISK ACTIVITIES.
//-------------------------------------------------------------------------
package com.password.safe.service.impl;

import java.security.SecureRandom;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import org.apache.log4j.Logger;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import com.password.safe.service.SecurityService;
import com.sun.crypto.provider.SunJCE;

public class SecurityServiceDESImpl extends SecurityServiceAbstractImpl {
	private static Logger logger = Logger.getLogger(SecurityServiceDESImpl.class);
	private static String ALGORITHM = "DES";
	private static String DEFAULT_KEY = "This is my key";
	private int keyLength = 8;
	
	@Override
	public String encode(String target) {
		return encode(DEFAULT_KEY, target);
	}
	
	@Override
	public String decode(String target) {
		return decode(DEFAULT_KEY, target);
	}
	
	@Override
	public String encode(String salt, String target) {
		String tempSalt = adjustSalt(salt);
		String result = "";
		SecureRandom secureRandom = new SecureRandom();
		Security.addProvider(new SunJCE());
		BASE64Encoder encoder = new BASE64Encoder();
		try {
			DESKeySpec keySpec = new DESKeySpec(tempSalt.getBytes());
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
			SecretKey key = keyFactory.generateSecret(keySpec);
			Cipher cipher = Cipher.getInstance(ALGORITHM);
			cipher.init(Cipher.ENCRYPT_MODE, key, secureRandom);
			byte[] data = target.getBytes();
			byte[] dataResult = cipher.doFinal(data);
			result = encoder.encode(dataResult);
		} catch (Exception e) {
			logger.debug(e.getMessage());
		}
		return result;
	}

	@Override
	public String decode(String salt, String target) {
		logger.debug("decode target string by salt");
		String tempSalt = adjustSalt(salt);
		String result = "";
		SecureRandom secureRandom = new SecureRandom();
		BASE64Decoder decoder = new BASE64Decoder();
		try {
			DESKeySpec keySpec = new DESKeySpec(tempSalt.getBytes());
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
			SecretKey key = keyFactory.generateSecret(keySpec);
			Cipher cipher = Cipher.getInstance(ALGORITHM);
			cipher.init(Cipher.DECRYPT_MODE, key, secureRandom);
			byte[] data = decoder.decodeBuffer(target);
			byte[] resultData = cipher.doFinal(data);
			result = new String(resultData);
		} catch (Exception e) {
			logger.debug(e.getMessage());
		}
		return result;
	}
	
	private String adjustSalt(String salt) {
		String tempSalt = salt;
		if (tempSalt == null) 
			tempSalt = DEFAULT_KEY;
		if (tempSalt.length() < keyLength) {
			tempSalt = (salt + DEFAULT_KEY).substring(0, keyLength);
		}
		return tempSalt;
	}
	
	public static void main(String[] args) {
		SecurityService service = new SecurityServiceDESImpl();
		String salt = "keyString";
		String salt2 = "keyString222";
		String orginal = "I will test des algorithm";
		System.out.println("orginal:" + orginal);
		String encode = service.encode(salt, orginal);
		System.out.println("encode:" + encode);
		String decode = service.decode(salt2, encode);
		System.out.println("decode:" + decode);
		//Uz7VlYCsownoR+enlCKxtRsWHjNRXC5REFnYxP9bsvQ=
		//Uz7VlYCsownoR+enlCKxtRsWHjNRXC5REFnYxP9bsvQ=
	}
}
